package com.gagakuai.transport.channel;

import com.gagakuai.utils.ResourceLeakHint;
import com.gagakuai.utils.concurrent.EventExecutor;
import com.gagakuai.utils.concurrent.OrderedEventExecutor;
import com.gagakuai.utils.internal.ObjectUtil;

import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/*
 * @description: 处理器上下文基类
 * @author: houhong
 * @create: 2024-03-30 16:31
 */
public abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, ResourceLeakHint {


    /*
     *  上下文名字
     */
    private final String name;

    private final DefaultChannelPipeline pipeline;

    final EventExecutor executor;

    private ChannelFuture successedFuture;


    private final boolean ordered;

    /*===========================线程安全处理=======================================*/

    private static final AtomicIntegerFieldUpdater<AbstractChannelHandlerContext> HANDLER_STATE_UPDATER =
            AtomicIntegerFieldUpdater.newUpdater(AbstractChannelHandlerContext.class, "handlerState");


    private static final int INIT = 0;

    private static final int ADD_PENDING = 1;
    /*
     * {@link ChannelHandler#handlerAdded(ChannelHandlerContext)} was called.
     */
    private static final int ADD_COMPLETE = 2;
    /*
     * {@link ChannelHandler#handlerRemoved(ChannelHandlerContext)} was called.
     */
    private static final int REMOVE_COMPLETE = 3;

    private volatile int handlerState = INIT;


    public AbstractChannelHandlerContext(DefaultChannelPipeline pipeline, EventExecutor eventExecutor,
                                         String name, Class<DefaultChannelPipeline.TailContext> tailContextClass) {


        this.name = ObjectUtil.checkNotNull(name, "name");
        this.pipeline = pipeline;
        this.executor = eventExecutor;


        ordered = executor == null || executor instanceof OrderedEventExecutor;
    }


    /*===========================共同方法==========================================================*/
    public final boolean setAddCompleted() {


        for (; ; ) {

            int oldState = handlerState;

            if (oldState == REMOVE_COMPLETE) {
                return false;
            }

            if (HANDLER_STATE_UPDATER.compareAndSet(this, oldState, ADD_COMPLETE)) {
                return true;
            }
        }
    }


}
